﻿using ClientAppraise.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Wpf.Ui.Controls;
using Wpf.Ui;
using System.Windows.Controls;

namespace ClientAppraise.Services.Impl
{
    public class ZxSnackbarService : IZxSnackbarService
    {
        private readonly List<KeyValuePair<int, SnackbarPresenter>> contents = new();

        private Snackbar? _snackbar;
        public TimeSpan DefaultTimeOut { get; set; } = TimeSpan.FromSeconds(2);

        public void Caution(string title, int timeout = 0) {
             Caution(title, title, timeout);
        }
        public void Caution(string title, string message, int timeout = 0)
        {
            Show(title, message, ControlAppearance.Caution, null, TimeSpan.FromSeconds(timeout));
        }

        public void Clear()
        {
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                Application.Current.Dispatcher.Invoke(new Action(() => Clear()));
                return;
            }

            var presenter = (ZxSnackbarPresenter)GetSnackbarPresenter();

            presenter.Content.Children.Clear();
        }
        public void Danger(string title,  int timeout = 0) {
            Danger(title, title, timeout);
        }
        public void Danger(string title, string message, int timeout = 0)
        {
            Show(title, message, ControlAppearance.Danger, null, TimeSpan.FromSeconds(timeout == 0 ? 5 : timeout));
        }

        public SnackbarPresenter EjectContentPresenter(int HashCode)
        {
            var value = contents.FirstOrDefault(t => t.Key == HashCode);

            if (!value.Equals(default(KeyValuePair<int, ContentPresenter>)))
            {
                contents.Remove(value);
            }

            var myReturn = value.Equals(default(KeyValuePair<int, ContentPresenter>)) ? value.Value : null;

            return myReturn ?? throw new InvalidOperationException();
        }
        public SnackbarPresenter GetSnackbarPresenter()
        {
            var code = 0;
            foreach (Window window in Application.Current.Windows)
            {
                if (window.IsActive)//使用窗体类进行匹配查找
                {
                    code = window.GetHashCode();
                    break;
                }
            }


            return GetSnackbarPresenter(code);
        }
        public SnackbarPresenter GetSnackbarPresenter(int HashCode)
        {
            if (!contents.Any(t => t.Key == HashCode))
            {
                if (contents.Count > 0)
                {
                    return contents[^1].Value;
                }
            }

            var myReturn = contents.FirstOrDefault(t => t.Key == HashCode);

            return myReturn.Value;
        }
        public void Info(string title,  int timeout = 0) {
            Info(title, title, timeout);
        }
        public void Info(string title, string message, int timeout = 0)
        {
            Show(title, message, ControlAppearance.Info, null, TimeSpan.FromSeconds(timeout));
        }

        public void PushContentPresenter(int HashCode, SnackbarPresenter? contentPresenter)
        {
            if (contentPresenter == null) return;

            var value = contents.FirstOrDefault(t => t.Key == HashCode);

            if (value.Equals(default(KeyValuePair<int, SnackbarPresenter>)))
            {
                contents.Add(new KeyValuePair<int, SnackbarPresenter>(HashCode, contentPresenter));
            }
        }
        public void SetSnackbarPresenter(SnackbarPresenter contentPresenter)
        {
            var code = 0;
            foreach (Window window in Application.Current.Windows)
            {
                if (window.IsActive)//使用窗体类进行匹配查找
                {
                    code = window.GetHashCode();
                    break;
                }
            }
            contents.Clear();
            PushContentPresenter(code, contentPresenter);
        }
        public void Show(string title, string message, ControlAppearance appearance = ControlAppearance.Secondary, IconElement? icon = null, TimeSpan timeout = default)
        {
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                Application.Current.Dispatcher.Invoke(new Action(() => Show(title, message, appearance, icon, timeout)));
                return;
            }

            var presenter = GetSnackbarPresenter();

            if (presenter == null)
            {
                throw new ArgumentNullException($"The SnackbarPresenter didn't set previously.");
            }

            _snackbar = new Snackbar(presenter)
            {
                Title = title,
                Content = message,
                Margin = new Thickness(2),
                Appearance = appearance,
                Icon = icon,
                Timeout = timeout.TotalSeconds == 0 ? DefaultTimeOut : timeout
            };

            _snackbar.Show(true);
        }

        public void Success(string title,  int timeout = 0) {
            Success(title, title, timeout);
        }
        public void Success(string title, string message, int timeout = 0)
        {
            Show(title, message, ControlAppearance.Success, null, TimeSpan.FromSeconds(timeout));
        }

        public void UnSetSnackbarPresenter()
        {
            contents.Clear();
        }

        /*
        void Show(string title, string message) => Show(title, message, ControlAppearance.Secondary, null);
        void Show(string title, string message, ControlAppearance appearance) => Show(title, message, appearance, null);
        void Show(string title, string message, IconElement icon) => Show(title, message, ControlAppearance.Secondary, icon);
        void Show(string title, string message, TimeSpan timeout) => Show(title, message, ControlAppearance.Secondary, null, timeout);
        void Show(string title, string message, ControlAppearance appearance, TimeSpan timeout) => Show(title, message, appearance, null, timeout);
        void Show(string title, string message, IconElement icon, TimeSpan timeout) => Show(title, message, ControlAppearance.Secondary, icon, timeout);
        */
    }

}
